using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using LTKJ.DataBase;

namespace LTKJ.RTU
{
    /// <summary>
    /// 数据缓存管理器 - 专业级缓存解决方案
    /// </summary>
    public class DataCacheManager : IDisposable
    {
        private readonly ConcurrentDictionary<string, CachedDeviceData> deviceCache;
        private readonly ConcurrentQueue<DeviceDataUpdate> updateQueue;
        private readonly System.Threading.Timer flushTimer;
        private readonly System.Threading.Timer cleanupTimer;
        private readonly object cacheLock = new object();
        private readonly int maxCacheSize = 1000;
        private readonly int flushIntervalMs = 5000; // 5秒批量刷新
        private readonly int cleanupIntervalMs = 300000; // 5分钟清理一次
        private volatile bool isDisposed = false;

        public event Action<string> OnCacheFlush;
        public event Action<string> OnCacheError;

        public DataCacheManager()
        {
            deviceCache = new ConcurrentDictionary<string, CachedDeviceData>();
            updateQueue = new ConcurrentQueue<DeviceDataUpdate>();
            
            // 启动定时刷新
            flushTimer = new System.Threading.Timer(FlushCacheToDatabase, null, flushIntervalMs, flushIntervalMs);
            
            // 启动定时清理
            cleanupTimer = new System.Threading.Timer(CleanupExpiredData, null, cleanupIntervalMs, cleanupIntervalMs);
        }

        /// <summary>
        /// 缓存设备数据
        /// </summary>
        public void CacheDeviceData(string deviceId, ModelDevice deviceData)
        {
            if (isDisposed) return;

            try
            {
                var cachedData = new CachedDeviceData
                {
                    DeviceId = deviceId,
                    Data = deviceData,
                    LastUpdateTime = DateTime.Now,
                    UpdateCount = 1
                };

                deviceCache.AddOrUpdate(deviceId, cachedData, (key, existing) =>
                {
                    existing.Data = deviceData;
                    existing.LastUpdateTime = DateTime.Now;
                    existing.UpdateCount++;
                    return existing;
                });

                // 添加到更新队列
                updateQueue.Enqueue(new DeviceDataUpdate
                {
                    DeviceId = deviceId,
                    Data = deviceData,
                    Timestamp = DateTime.Now
                });

                // 检查缓存大小
                if (deviceCache.Count > maxCacheSize)
                {
                    CleanupOldestData();
                }
            }
            catch (Exception ex)
            {
                OnCacheError?.Invoke($"缓存数据异常: {ex.Message}");
            }
        }

        /// <summary>
        /// 获取缓存的设备数据
        /// </summary>
        public ModelDevice GetCachedData(string deviceId)
        {
            if (isDisposed) return null;

            try
            {
                if (deviceCache.TryGetValue(deviceId, out var cachedData))
                {
                    // 检查数据是否过期（超过1小时）
                    if (DateTime.Now - cachedData.LastUpdateTime < TimeSpan.FromHours(1))
                    {
                        return cachedData.Data;
                    }
                    else
                    {
                        // 移除过期数据
                        deviceCache.TryRemove(deviceId, out _);
                    }
                }
            }
            catch (Exception ex)
            {
                OnCacheError?.Invoke($"获取缓存数据异常: {ex.Message}");
            }

            return null;
        }

        /// <summary>
        /// 批量刷新缓存到数据库
        /// </summary>
        private async void FlushCacheToDatabase(object state)
        {
            if (isDisposed) return;

            try
            {
                var updates = new List<DeviceDataUpdate>();
                var maxBatchSize = 100; // 限制批量大小，避免一次性处理过多数据
                
                // 收集待更新的数据，限制批量大小
                while (updateQueue.TryDequeue(out var update) && updates.Count < maxBatchSize)
                {
                    updates.Add(update);
                }

                if (updates.Count > 0)
                {
                    // 使用信号量控制并发数量
                    using (var semaphore = new SemaphoreSlim(1, 1))
                    {
                        await semaphore.WaitAsync();
                        try
                        {
                            await Task.Run(() => ProcessBatchUpdates(updates));
                            OnCacheFlush?.Invoke($"批量更新完成，共处理 {updates.Count} 条数据");
                        }
                        finally
                        {
                            semaphore.Release();
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                OnCacheError?.Invoke($"批量刷新异常: {ex.Message}");
            }
        }

        /// <summary>
        /// 处理批量数据更新
        /// </summary>
        private void ProcessBatchUpdates(List<DeviceDataUpdate> updates)
        {
            try
            {
                // 按设备ID分组处理
                var groupedUpdates = updates.GroupBy(u => u.DeviceId).ToList();
                
                foreach (var group in groupedUpdates)
                {
                    try
                    {
                        var latestData = group.OrderByDescending(u => u.Timestamp).First();
                        InsertDeviceData(latestData.Data);
                    }
                    catch (Exception ex)
                    {
                        OnCacheError?.Invoke($"处理设备 {group.Key} 数据异常: {ex.Message}");
                    }
                }
            }
            catch (Exception ex)
            {
                OnCacheError?.Invoke($"批量更新处理异常: {ex.Message}");
            }
        }

        /// <summary>
        /// 插入设备数据到数据库
        /// </summary>
        private void InsertDeviceData(ModelDevice deviceData)
        {
            try
            {
                // 这里需要调用主窗体的方法，通过事件或委托来实现
                // 暂时使用反射调用，或者通过构造函数传入委托
                OnDataInsertRequested?.Invoke(deviceData);
            }
            catch (Exception ex)
            {
                OnCacheError?.Invoke($"插入数据异常: {ex.Message}");
            }
        }

        /// <summary>
        /// 清理过期数据
        /// </summary>
        private void CleanupExpiredData(object state)
        {
            if (isDisposed) return;

            try
            {
                var expiredKeys = new List<string>();
                var cutoffTime = DateTime.Now.AddHours(-2); // 2小时前的数据

                foreach (var kvp in deviceCache)
                {
                    if (kvp.Value.LastUpdateTime < cutoffTime)
                    {
                        expiredKeys.Add(kvp.Key);
                    }
                }

                foreach (var key in expiredKeys)
                {
                    deviceCache.TryRemove(key, out _);
                }

                if (expiredKeys.Count > 0)
                {
                    OnCacheFlush?.Invoke($"清理过期数据完成，共清理 {expiredKeys.Count} 条");
                }
            }
            catch (Exception ex)
            {
                OnCacheError?.Invoke($"清理过期数据异常: {ex.Message}");
            }
        }

        /// <summary>
        /// 清理最旧的数据
        /// </summary>
        private void CleanupOldestData()
        {
            try
            {
                var oldestData = deviceCache.Values
                    .OrderBy(d => d.LastUpdateTime)
                    .Take(deviceCache.Count / 4) // 清理1/4的数据
                    .ToList();

                foreach (var data in oldestData)
                {
                    deviceCache.TryRemove(data.DeviceId, out _);
                }
            }
            catch (Exception ex)
            {
                OnCacheError?.Invoke($"清理旧数据异常: {ex.Message}");
            }
        }

        /// <summary>
        /// 获取缓存统计信息
        /// </summary>
        public CacheStatistics GetCacheStatistics()
        {
            return new CacheStatistics
            {
                TotalCachedItems = deviceCache.Count,
                PendingUpdates = updateQueue.Count,
                CacheSizeMB = GetCacheSizeInMB(),
                LastFlushTime = DateTime.Now
            };
        }

        /// <summary>
        /// 获取缓存大小（MB）
        /// </summary>
        private long GetCacheSizeInMB()
        {
            try
            {
                var totalSize = deviceCache.Values.Sum(d => 
                    System.Runtime.InteropServices.Marshal.SizeOf(d.Data) + 
                    System.Runtime.InteropServices.Marshal.SizeOf(d.DeviceId));
                return totalSize / (1024 * 1024);
            }
            catch
            {
                return 0;
            }
        }

        /// <summary>
        /// 强制刷新缓存
        /// </summary>
        public void ForceFlush()
        {
            FlushCacheToDatabase(null);
        }

        /// <summary>
        /// 清空缓存
        /// </summary>
        public void ClearCache()
        {
            deviceCache.Clear();
            while (updateQueue.TryDequeue(out _)) { }
        }

        public void Dispose()
        {
            if (!isDisposed)
            {
                isDisposed = true;
                
                // 停止定时器
                flushTimer?.Change(Timeout.Infinite, Timeout.Infinite);
                cleanupTimer?.Change(Timeout.Infinite, Timeout.Infinite);
                
                // 强制刷新剩余数据
                ForceFlush();
                
                flushTimer?.Dispose();
                cleanupTimer?.Dispose();
                
                ClearCache();
            }
        }

        // 这些方法需要从主窗体中调用，暂时声明为虚方法
        protected virtual void AddRunData(ModelDevice deviceData, bool showMessage) { }
        protected virtual void AddFlowRunData(ModelDevice deviceData, bool showMessage) { }

        // 添加事件，用于通知主窗体插入数据
        public event Action<ModelDevice> OnDataInsertRequested;
    }

    /// <summary>
    /// 缓存的设备数据
    /// </summary>
    public class CachedDeviceData
    {
        public string DeviceId { get; set; }
        public ModelDevice Data { get; set; }
        public DateTime LastUpdateTime { get; set; }
        public int UpdateCount { get; set; }
    }

    /// <summary>
    /// 设备数据更新
    /// </summary>
    public class DeviceDataUpdate
    {
        public string DeviceId { get; set; }
        public ModelDevice Data { get; set; }
        public DateTime Timestamp { get; set; }
    }

    /// <summary>
    /// 缓存统计信息
    /// </summary>
    public class CacheStatistics
    {
        public int TotalCachedItems { get; set; }
        public int PendingUpdates { get; set; }
        public long CacheSizeMB { get; set; }
        public DateTime LastFlushTime { get; set; }
    }
}
